#include "MiniMap.h"
#include "CameraManager.h"
#include "DX11HelpfulFunctions.h"
#include "Game.h"
#include "ScreenManager.h"
#include "Get3DMousePos.h"
#include "DX11TextureManager.h"

MiniMap::MiniMap()
{	
	m_pRenderTargetTexture = NULL;
	m_pRenderTargetView = NULL;
	m_pShaderResourceView = NULL;
	m_pRTTGameObjects = NULL;
	m_pRTVGameObjects = NULL;
	m_pSRVGameObjects = NULL;
	m_pRTTFogOfWar = NULL;
	m_pRTVFogOfWar = NULL;
	m_pSRVFogOfWar = NULL;
	m_pRTTFogOfWarFin = NULL;
	m_pRTVFogOfWarFin = NULL;
	m_pSRVFogOfWarFin = NULL;
	
	DX11::InitRenderToTexture(&m_pRenderTargetTexture, &m_pRenderTargetView, &m_pShaderResourceView);
	DX11::InitRenderToTexture(&m_pRTTGameObjects, &m_pRTVGameObjects, &m_pSRVGameObjects);
	DX11::InitRenderToTexture(&m_pRTTGameObjectsColPick, &m_pRTVGameObjectsColPick, &m_pSRVGameObjectsColPick);
	DX11::InitRenderToTexture(&m_pRTTFogOfWar, &m_pRTVFogOfWar, &m_pSRVFogOfWar);
	DX11::InitRenderToTexture(&m_pRTTFogOfWarFin, &m_pRTVFogOfWarFin, &m_pSRVFogOfWarFin);
	
	TheObjMeshManager::Instance()->ChangeTexture2("mini_map", m_pSRVFogOfWarFin);


	m_lArrowDown = false;
	m_rArrowDown = false;
	m_mapRendered = false;

	//m_position = D3DXVECTOR2(0.7f, 0.6f);
	m_position = D3DXVECTOR2(0.5f, 0.5f);

	m_screenW = TheScreenManager::Instance()->GetWindowWidth();
	m_screenH = TheScreenManager::Instance()->GetWindowHeight();

	// scaling
	float aspectRat;
	float size = 0.8f;
	aspectRat = TheScreenManager::Instance()->GetAspectRatio();
	//aspectRat = 1.0f;
	if (aspectRat != 1.0f)
	{
		if (m_screenH > m_screenW)
		{
			m_scale = D3DXVECTOR2(size, size / aspectRat);
		}
		else
		{
			m_scale = D3DXVECTOR2(size / aspectRat, size);
		}
	}
	else
	{
		m_scale = D3DXVECTOR2(size, size);
	}
	m_scale = D3DXVECTOR2(0.5f * aspectRat, 0.5f * aspectRat);

	m_width = int((m_screenW * 0.5f) * m_scale.x);
	m_height = int((m_screenH * 0.5f) * m_scale.y);

	// convert m_position to m_screenPos in pixels
	m_screenPos.x = (m_screenW * 0.5f) * m_position.x;
	m_screenPos.y = (m_screenH * 0.5f) * m_position.y * -1.0f;

	m_screenPos.x -= ((m_screenW * 0.5f) - m_screenW);
	m_screenPos.y += m_screenH * 0.5f;

	m_clearColour = D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f);
	m_lMouseButtonDown = false;
	m_mouseIntersected = false;

	m_camRot = 0;

	TheEventPoller::Instance()->AddHandler(this);
}

MiniMap::~MiniMap()
{
	TheEventPoller::Instance()->RemoveHandler(this);
	
	if (m_pRenderTargetTexture) m_pRenderTargetTexture->Release();
	if (m_pRenderTargetView) m_pRenderTargetView->Release();
	if (m_pShaderResourceView) m_pShaderResourceView->Release();

	if (m_pRTTGameObjects) m_pRTTGameObjects->Release();
	if (m_pRTVGameObjects) m_pRTVGameObjects->Release();
	if (m_pSRVGameObjects) m_pSRVGameObjects->Release();

	if (m_pRTTGameObjectsColPick) m_pRTTGameObjectsColPick->Release();
	if (m_pRTVGameObjectsColPick) m_pRTVGameObjectsColPick->Release();
	if (m_pSRVGameObjectsColPick) m_pSRVGameObjectsColPick->Release();

	if (m_pRTTFogOfWar) m_pRTTFogOfWar->Release();
	if (m_pRTVFogOfWar) m_pRTVFogOfWar->Release();
	if (m_pSRVFogOfWar) m_pSRVFogOfWar->Release();

	if (m_pRTTFogOfWarFin) m_pRTTFogOfWarFin->Release();
	if (m_pRTVFogOfWarFin) m_pRTVFogOfWarFin->Release();
	if (m_pSRVFogOfWarFin) m_pSRVFogOfWarFin->Release();
}

void MiniMap::Draw()
{
	//TheScreenManager::Instance()->EnableBlending();
	//
	//TheObjMeshManager::Instance()->ChangeShader("mini_map", "mini_map_1");
	//TheObjMeshManager::Instance()->ChangeTexture("mini_map", m_pSRVFogOfWarFin);
	//TheObjMeshManager::Instance()->Translate("mini_map", D3DXVECTOR3(m_position.x, m_position.y, 0.005f));
	//TheObjMeshManager::Instance()->Rotate("mini_map", m_camRot, 0.0f, 0.0f, 1.0f);
	////TheObjMeshManager::Instance()->Rotate("maze_floor", M_PI, 0.0f, 0.0f, 1.0f);
	//TheObjMeshManager::Instance()->Scale("mini_map", D3DXVECTOR3(m_scale.x, m_scale.y, 1.0f));
	//TheObjMeshManager::Instance()->Draw("mini_map");

	m_camRot = TheCameraManager::Instance()->GetCameraRotation();

	TheCameraManager::Instance()->UpdateHUD();
	
	TheScreenManager::Instance()->EnableBlending();

	TheObjMeshManager::Instance()->ChangeShader("mini_map", "MiniMapShader2");
	TheObjMeshManager::Instance()->ChangeTexture("mini_map", m_pShaderResourceView);
	TheObjMeshManager::Instance()->Translate("mini_map", D3DXVECTOR3(m_position.x, m_position.y, 0.005f));
	TheObjMeshManager::Instance()->Rotate("mini_map", m_camRot, 0.0f, 0.0f, 1.0f);
	TheObjMeshManager::Instance()->Scale("mini_map", D3DXVECTOR3(m_scale.x, m_scale.y, 1.0f));
	TheObjMeshManager::Instance()->Draw("mini_map");
	
	//TheScreenManager::Instance()->EnableBlending();

	TheObjMeshManager::Instance()->ChangeTexture("mini_map", m_pSRVGameObjects);
	TheObjMeshManager::Instance()->Translate("mini_map", D3DXVECTOR3(m_position.x, m_position.y, 0.0f));
	TheObjMeshManager::Instance()->Rotate("mini_map", m_camRot, 0.0f, 0.0f, 1.0f);
	TheObjMeshManager::Instance()->Scale("mini_map", D3DXVECTOR3(m_scale.x, m_scale.y, 1.0f));
	TheObjMeshManager::Instance()->Draw("mini_map");

	TheCameraManager::Instance()->Update();

	TheScreenManager::Instance()->DisableBlending();	

	//static Text t;
	//t.Update("R: " + ToString(m_pickedColour.x));
	//t.Translate(D3DXVECTOR3(0.0f, 0.7f, 0.0f));
	//t.Draw();
	//t.Update("G: " + ToString(m_pickedColour.y));
	//t.Translate(D3DXVECTOR3(0.0f, 0.6f, 0.0f));
	//t.Draw();
	//t.Update("B: " + ToString(m_pickedColour.z));
	//t.Translate(D3DXVECTOR3(0.0f, 0.5f, 0.0f));
	//t.Draw();
}

void MiniMap::DrawColourPick()
{	
	m_camRot = TheCameraManager::Instance()->GetCameraRotation();

	// draw finished mask and then check if player clicked on a white pixel
	// if yes then check the rest, else return (-1, -1 -1)
	
	TheObjMeshManager::Instance()->ChangeShader("mini_map", "mini_map_1");
	TheObjMeshManager::Instance()->ChangeTexture("mini_map", m_pSRVFogOfWarFin);
	TheObjMeshManager::Instance()->Translate("mini_map", D3DXVECTOR3(m_position.x, m_position.y, 0.01f));
	TheObjMeshManager::Instance()->Rotate("mini_map", m_camRot, 0.0f, 0.0f, 1.0f);
	TheObjMeshManager::Instance()->Scale("mini_map", D3DXVECTOR3(m_scale.x, m_scale.y, 1.0f));
	TheObjMeshManager::Instance()->Draw("mini_map");

	int pickedMaskCol = 255;
	if (m_lMouseButtonDown)
	{
		if (m_mouseIntersected)
		{
			pickedMaskCol = PickColour(D3DXVECTOR2((float)m_mouseX, (float)m_mouseY));
		}
	}

	if (pickedMaskCol == 255)
	{	
		TheObjMeshManager::Instance()->ChangeShader("mini_map", "mini_map_1");
		TheObjMeshManager::Instance()->ChangeTexture("mini_map", m_pSRVGameObjectsColPick);
		TheObjMeshManager::Instance()->Translate("mini_map", D3DXVECTOR3(m_position.x, m_position.y, 0.001f));
		TheObjMeshManager::Instance()->Rotate("mini_map", m_camRot, 0.0f, 0.0f, 1.0f);
		TheObjMeshManager::Instance()->Scale("mini_map", D3DXVECTOR3(m_scale.x, m_scale.y, 1.0f));
		TheObjMeshManager::Instance()->Draw("mini_map");
	
		m_screenPos.x = (m_screenW * 0.5f) * m_position.x;
		m_screenPos.y = (m_screenH * 0.5f) * m_position.y * -1.0f;

		m_screenPos.x -= ((m_screenW * 0.5f) - m_screenW);
		m_screenPos.y += m_screenH * 0.5f;
	
		if (m_lMouseButtonDown)
		{
			if (m_mouseIntersected)
			{
				m_pickedColour = PickColourRGBA(D3DXVECTOR2((float)m_mouseX, (float)m_mouseY));
			}
		}
		else
		{
			m_pickedColour = D3DXVECTOR4(-1, -1, -1, -1);
		}
	}
}
	 
void MiniMap::RenderMap()
{
	if (!m_mapRendered)
	{
		//float ClearColour[] = {m_clearColour.x, m_clearColour.y, m_clearColour.z, m_clearColour.y};
		float ClearColour[] = {0.0f, 0.0f, 0.0f, 0.0f};
		DX11::CreateRenderTexture(&m_pRenderTargetView, &m_pShaderResourceView, ClearColour);
		TheCameraManager::Instance()->UpdateMiniMap();

		TheGame::Instance()->DrawMiniMapGameObjects();
		
		float ClearColour2[] = {1.0f, 1.0f, 1.0f, 1.0f};
		DX11::CreateRenderTexture(&m_pRTVGameObjectsColPick, &m_pSRVGameObjectsColPick, ClearColour2);
		//TheCameraManager::Instance()->UpdateMiniMap();

		TheGame::Instance()->DrawMiniMapColourPickObjects();

		DX11::CreateRenderTexture(&m_pRTVFogOfWar, &m_pSRVFogOfWar, ClearColour);
		TheCameraManager::Instance()->UpdateMiniMap();
		DX11::CreateRenderTexture(&m_pRTVFogOfWarFin, &m_pSRVFogOfWarFin, ClearColour);
		TheCameraManager::Instance()->UpdateMiniMap();
		
		m_mapRendered = true;
	}
	else
	{
		// now render the game objects
		
		float ClearColour[] = {0.0f, 0.0f, 0.0f, 0.0f};
		DX11::CreateRenderTexture(&m_pRTVGameObjects, &m_pSRVGameObjects, ClearColour);
		TheCameraManager::Instance()->UpdateMiniMap();

		TheGame::Instance()->DrawMiniMapGameObjects();


		
	// sets render target
	TheScreenManager::Instance()->GetDeviceContext()->OMSetRenderTargets(1, &m_pRTVFogOfWarFin, 
		TheScreenManager::Instance()->GetDepthStencilView());
	// clears render target
	//TheScreenManager::Instance()->GetDeviceContext()->ClearRenderTargetView(m_pRTVFogOfWarFin, ClearColour);
	// clears depth buffer	
	TheScreenManager::Instance()->GetDeviceContext()->ClearDepthStencilView(
		TheScreenManager::Instance()->GetDepthStencilView(), D3D11_CLEAR_DEPTH, 1, 0);

		
		//TheObjMeshManager::Instance()->ChangeTexture("maze_floor", TheDX11TextureManager::Instance()->UseTexture(L"../../Assets/fog_of_war.png"));
		//TheObjMeshManager::Instance()->ChangeShader("maze_floor", "DefaultTexture");

//		D3DXVECTOR3 m_gridCellSize = TheGame::Instance()->GetMaze()->GetCellSize();
//		D3DXVECTOR2 m_gridSize = TheGame::Instance()->GetMaze()->GetGridSize();

		D3DXVECTOR3 camPos = TheCameraManager::Instance()->GetCameraPos();
		//camPos.z += 10.0f;
		//camPos.x += m_gridCellSize.x * (m_gridSize.x * 0.5f);
		//camPos.z += m_gridCellSize.z * (m_gridSize.y * 0.5f) - m_gridCellSize.z;
		TheObjMeshManager::Instance()->SetColour("sphere", D3DXVECTOR4(1.0f, 1.0f, 1.0f, 1.0f));
		TheObjMeshManager::Instance()->Translate("sphere", camPos);
//		TheObjMeshManager::Instance()->Scale("sphere", D3DXVECTOR3(m_gridCellSize.x * 1.7f, 1, m_gridCellSize.z * 1.7f));
		TheObjMeshManager::Instance()->Draw("sphere");
		TheObjMeshManager::Instance()->ChangeShader("sphere", "sphere_1");


		
		//DX11::CreateRenderTexture(&m_pRTVFogOfWar, &m_pSRVFogOfWar, ClearColour);
		//TheCameraManager::Instance()->UpdateMiniMap();
		//		
		//TheScreenManager::Instance()->EnableBlendingNB();

		//TheObjMeshManager::Instance()->ChangeTexture("maze_floor", m_pSRVFogOfWarFin);
		//TheObjMeshManager::Instance()->ChangeShader("maze_floor", "DefaultTexture");
		//TheObjMeshManager::Instance()->Scale("maze_floor", D3DXVECTOR3(500, 1, 500)); // small in z
		//TheObjMeshManager::Instance()->Draw("maze_floor");

		//TheObjMeshManager::Instance()->ChangeTexture("maze_floor", TheDX11TextureManager::Instance()->UseTexture(L"../../Assets/fog_of_war.png"));
		//TheObjMeshManager::Instance()->ChangeShader("maze_floor", "DefaultTexture");
		//static float x = 0;
		//x += 1.0f;
		//TheObjMeshManager::Instance()->Translate("maze_floor", D3DXVECTOR3(x, 1.0f, 0.0f));
		//TheObjMeshManager::Instance()->Scale("maze_floor", D3DXVECTOR3(100, 1, 100));
		//TheObjMeshManager::Instance()->Draw("maze_floor");
		//TheObjMeshManager::Instance()->ChangeShader("maze_floor", "maze_floor_1");

		//TheScreenManager::Instance()->DisableBlending();
		//
		//DX11::CreateRenderTexture(&m_pRTVFogOfWarFin, &m_pSRVFogOfWarFin, ClearColour);
		//TheCameraManager::Instance()->UpdateMiniMap();
		//
		////TheObjMeshManager::Instance()->ChangeTexture("maze_floor", m_pSRVFogOfWar);
		////TheObjMeshManager::Instance()->ChangeShader("maze_floor", "DefaultTexture");
		////TheObjMeshManager::Instance()->Scale("maze_floor", D3DXVECTOR3(500, 1, 500)); // small in z
		////TheObjMeshManager::Instance()->Draw("maze_floor");
		//
		//TheObjMeshManager::Instance()->ChangeTexture("maze_floor", TheDX11TextureManager::Instance()->UseTexture(L"../../Assets/fog_of_war.png"));
		//TheObjMeshManager::Instance()->ChangeShader("maze_floor", "DefaultTexture");
		//TheObjMeshManager::Instance()->Translate("maze_floor", D3DXVECTOR3(x + 10.0f, 1.0f, 0.0f));
		//TheObjMeshManager::Instance()->Scale("maze_floor", D3DXVECTOR3(100, 1, 100));
		//TheObjMeshManager::Instance()->Draw("maze_floor");
		//TheObjMeshManager::Instance()->ChangeShader("maze_floor", "maze_floor_1");

	}
}

void MiniMap::Reset()
{
	//if (m_pRenderTargetTexture) m_pRenderTargetTexture->Release();
	//if (m_pRenderTargetView) m_pRenderTargetView->Release();
	//if (m_pShaderResourceView) m_pShaderResourceView->Release();

	//if (m_pRTTGameObjects) m_pRTTGameObjects->Release();
	//if (m_pRTVGameObjects) m_pRTVGameObjects->Release();
	//if (m_pSRVGameObjects) m_pSRVGameObjects->Release();

	//if (m_pRTTGameObjectsColPick) m_pRTTGameObjectsColPick->Release();
	//if (m_pRTVGameObjectsColPick) m_pRTVGameObjectsColPick->Release();
	//if (m_pSRVGameObjectsColPick) m_pSRVGameObjectsColPick->Release();

	//if (m_pRTTFogOfWar) m_pRTTFogOfWar->Release();
	//if (m_pRTVFogOfWar) m_pRTVFogOfWar->Release();
	//if (m_pSRVFogOfWar) m_pSRVFogOfWar->Release();

	//if (m_pRTTFogOfWarFin) m_pRTTFogOfWarFin->Release();
	//if (m_pRTVFogOfWarFin) m_pRTVFogOfWarFin->Release();
	//if (m_pSRVFogOfWarFin) m_pSRVFogOfWarFin->Release();

	//
	//m_pRenderTargetTexture = NULL;
	//m_pRenderTargetView = NULL;
	//m_pShaderResourceView = NULL;
	//m_pRTTGameObjects = NULL;
	//m_pRTVGameObjects = NULL;
	//m_pSRVGameObjects = NULL;
	//m_pRTTFogOfWar = NULL;
	//m_pRTVFogOfWar = NULL;
	//m_pSRVFogOfWar = NULL;
	//m_pRTTFogOfWarFin = NULL;
	//m_pRTVFogOfWarFin = NULL;
	//m_pSRVFogOfWarFin = NULL;
	//
	//DX11::InitRenderToTexture(&m_pRenderTargetTexture, &m_pRenderTargetView, &m_pShaderResourceView);
	//DX11::InitRenderToTexture(&m_pRTTGameObjects, &m_pRTVGameObjects, &m_pSRVGameObjects);
	//DX11::InitRenderToTexture(&m_pRTTGameObjectsColPick, &m_pRTVGameObjectsColPick, &m_pSRVGameObjectsColPick);
	//DX11::InitRenderToTexture(&m_pRTTFogOfWar, &m_pRTVFogOfWar, &m_pSRVFogOfWar);
	//DX11::InitRenderToTexture(&m_pRTTFogOfWarFin, &m_pRTVFogOfWarFin, &m_pSRVFogOfWarFin);

	m_mapRendered = false;
}

bool MiniMap::MouseIntersected()
{
	m_boundingBox.top = int(m_screenPos.y - (m_height * 0.5f));
	m_boundingBox.bottom = int(m_screenPos.y + (m_height * 0.5f));
	m_boundingBox.left = int(m_screenPos.x - (m_width * 0.5f));
	m_boundingBox.right = int(m_screenPos.x + (m_width * 0.5f));

	bool x = false, y = false;
	if ((UINT)m_mouseX <= m_boundingBox.right && (UINT)m_mouseX >= m_boundingBox.left)
	{
		x = true;
	}
	if ((UINT)m_mouseY <= m_boundingBox.bottom && (UINT)m_mouseY >= m_boundingBox.top)
	{
		y = true;
	}

	return (x && y);
}

D3DXVECTOR4 MiniMap::GetPickedColour() const
{
	return m_pickedColour;
}

bool MiniMap::GetCollided() const
{
	return m_mouseIntersected;
}

bool MiniMap::GetMapRendered() const
{
	return m_mapRendered;
}

void MiniMap::OnKeyDownEvent(const WPARAM& event)
{
	//if (event == VK_LEFT)
	//{
	//	m_position.x -= 0.01f;
	//}
	//else if (event == VK_RIGHT)
	//{
	//	m_position.x += 0.01f;
	//}
}

void MiniMap::OnKeyUpEvent(const WPARAM& event)
{

}

void MiniMap::OnMouseMotionEvent(const LPARAM& event)
{
	m_mouseX = LOWORD(event);
	m_mouseY = HIWORD(event);
	m_mouseIntersected = MouseIntersected();
}

void MiniMap::OnMouseButtonDownEvent(const MSG& event)
{
	if (event.message == WM_LBUTTONDOWN)
	{
		if (MouseIntersected())
		{
			m_lMouseButtonDown = true;
		}
	}
}

void MiniMap::OnMouseButtonUpEvent(const MSG& event)
{
	if (event.message == WM_LBUTTONUP)
	{
		m_lMouseButtonDown = false;
	}
}